package com.example.bigupload.service.impl;

import com.example.bigupload.mapper.FileInfoMapper;
import com.example.bigupload.service.FileDownloadService;
import com.example.bigupload.utils.MinioUtil;
import io.minio.GetObjectArgs;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Author Js
 * @Description
 * @Date 2024-10-28 20:57
 * @Version 1.0
 **/
@Service
public class FileDownloadServiceImpl implements FileDownloadService {
    @Resource
    private MinioUtil minioUtil;
    @Resource

    private FileInfoMapper fileInfoMapper;


    public void downloadFiles(ZipOutputStream zipOut) throws IOException, ExecutionException, InterruptedException {
        List<String> fileNames=fileInfoMapper.getAll().stream().map(auth->auth.getFilePath()).collect(Collectors.toList());

        String tempDirPath = "C:\\Users\\lenovo\\Desktop\\123" + File.separator + "minio_temp_" + UUID.randomUUID();
        File tempDir = new File(tempDirPath);
        if (!tempDir.mkdir()) {
            throw new RuntimeException("Failed to create temp directory: " + tempDirPath);
        }

        // 使用 CompletableFuture 处理多线程下载
        ExecutorService executorService = Executors.newFixedThreadPool(5); // 例如限制为5个线程

        CompletableFuture<Void>[] futures = new CompletableFuture[fileNames.size()];

        for (int i = 0; i < fileNames.size(); i++) {
            final String fileName = fileNames.get(i);
            futures[i] = CompletableFuture.runAsync(() -> downloadFileToTempDir(fileName, tempDir));
        }

        // 等待所有下载完成
        CompletableFuture<Void> allOf = CompletableFuture.allOf(futures);
        allOf.get();  // 阻塞，直到所有下载完成



        // 压缩文件为 ZIP
        for (File file : tempDir.listFiles()) {
            try (InputStream fileInputStream = Files.newInputStream(file.toPath())) {
                zipOut.putNextEntry(new ZipEntry(file.getName()));
                copy(fileInputStream, zipOut);  // 使用自定义的 copy 方法
                zipOut.closeEntry();
            }
        }

        // 清理临时目录
        deleteDirectory(tempDir);
    }

    // 下载文件到临时目录
    private void downloadFileToTempDir(String fileName, File tempDir) {
        try (InputStream inputStream = minioUtil.getObject("filetest",fileName)) {
            File tempFile = new File(tempDir, fileName);
            try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("Error occurred while downloading file: " + fileName, e);
        }
    }

    // 自定义方法来复制 InputStream 到 OutputStream
    private void copy(InputStream input, ZipOutputStream output) throws IOException {
        byte[] buffer = new byte[8192]; // 定义缓冲区
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
    }

    // 删除目录及其内容
    private void deleteDirectory(File directory) {
        if (directory.isDirectory()) {
            for (File file : directory.listFiles()) {
                deleteDirectory(file);
            }
        }
        directory.delete();
    }
}














